/*
 * Copyright 2008-2010 GP Software
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * AbstractScheduler.java | Created on Sep 1, 2010
 */

package org.gp.scheduler;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The abstract scheduler
 *
 * @author Paul Augustine C. Mendoza
 */
public abstract class AbstractJobScheduler implements JobScheduler {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private Scheduler jobScheduler;
    private SchedulerFactory schedulerFactory;
    private boolean hasInitialized;
    private String name;

    public AbstractJobScheduler() {
        this.name = this.getClass().getSimpleName();
    }

    protected abstract Scheduler getConcreteScheduler();

    protected abstract String getPropertyFilename();

    protected SchedulerFactory getSchedulerFactory() {
        return this.schedulerFactory;
    }

    protected Scheduler getScheduler() {
        return this.jobScheduler;
    }

    protected Logger getLogger() {
        return this.logger;
    }

    public void start() throws ScheduledJobException {
        logger.info("Starting " + this.name + "...");
        try {
            if (!hasInitialized) {
                initialize();
            }
            this.jobScheduler.start();
            logger.info(this.schedulerFactory.getAllSchedulers()
                    .size() + " schedulers started.");
        } catch (SchedulerException e) {
            throw new ScheduledJobException(e, this);
        }
    }

    private void initialize() throws SchedulerException {
        this.schedulerFactory = new StdSchedulerFactory(getPropertyFilename());
        this.jobScheduler = getConcreteScheduler();
        this.hasInitialized = true;
    }

    public void standBy() throws ScheduledJobException {
        logger.info("Scheduler " + this.name + " is standing by...");
        try {
            this.jobScheduler.standby();
        } catch (SchedulerException e) {
            throw new ScheduledJobException(e, this);
        }
    }

    public void stop() throws ScheduledJobException {
        logger.info("Shutting down " + this.name + "...");
        try {
            this.jobScheduler.shutdown(true);
        } catch (SchedulerException e) {
            throw new ScheduledJobException(e, this);
        }
    }

    public boolean isJobStarted() {
        boolean flag = false;
        try {
            flag = this.jobScheduler.isStarted();
        } catch (SchedulerException e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }

    public boolean isJobTerminated() {
        boolean flag = false;
        try {
            flag = this.jobScheduler.isShutdown();
        } catch (SchedulerException e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }

    public boolean isInStandByMode() {
        boolean flag = false;
        try {
            flag = this.jobScheduler.isInStandbyMode();
        } catch (SchedulerException e) {
            logger.error(e.getMessage(), e);
        }
        return flag;
    }
}
